package automata;

import java.util.HashSet;
import java.util.Set;

public class State {

	private boolean isFinal;
	private boolean isInitial;
	private int id;
	private Set<Transition> transitions;

	public State(boolean isInitial, boolean isFinal, int id) {
		this.isInitial = isInitial;
		this.isFinal = isFinal;
		this.id = id;
		this.transitions = new HashSet<Transition>();
	}

	public void addTransition(char value, State destiny) throws Exception {

		if (value == '&')
			this.addLambdaTransition(destiny);
		else {
			Transition transition = new Transition(this, value, destiny);
			this.transitions.add(transition);
		}
	}

	public void addLambdaTransition(State destiny) {
        if (!this.equals(destiny)) {
		    Transition transition = new Transition(this, '&', destiny);
			this.transitions.add(transition);
        }
	}

	public boolean isFinal() {
		return isFinal;
	}

	public void setFinal(boolean isFinal) {
		this.isFinal = isFinal;
	}

	public boolean isInitial() {
		return isInitial;
	}

	public void setInitial(boolean isInitial) {
		this.isInitial = isInitial;
	}

	public int getId() {
	    return this.id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public Set<Transition> getTransitions() {
	    return this.transitions;
	}

	public boolean hasTransitionFor(Character symbol) {
		for(Transition transition: transitions) {
			if(transition.accept(symbol))
				return true;
		}
		return false;
	}

	public Transition getTransitionFor(Character symbol) {
		for(Transition transition: transitions) {
			if(transition.accept(symbol))
				return transition;
		}
		throw new RuntimeException("No existe transicion con simbolo '" + symbol + "' desde el estado " + this.toString());
	}
	
	public boolean hasLambdaTransition() {
		for(Transition transition: transitions) {
			if(transition.isLambda())
				return true;
		}
		return false;
	}
	
	public Set<Integer> getLambdaIds(){
		Set<Integer> result = new HashSet<Integer>();
		if(this.hasLambdaTransition()){
			for(Transition trans : transitions){
			 if(trans.isLambda()){
				 result.add(trans.getDestiny().getId());
			 }	
			}
		}
		return result;
	}
	
	public Set<Integer> getNeighboursFor(char c){
		Set<Integer> result = new HashSet<Integer>();
		for(Transition trans: transitions){
			if(trans.getValue() == c){
				result.add(trans.getDestiny().getId());
			}
		}
		return result;
	}
}
